基于角色的访问控制(RBAC)系统设计全过程(数据库以及java)项目 | 您所在的位置:网站首页 › 用户权限角色管理 图 › 基于角色的访问控制(RBAC)系统设计全过程(数据库以及java)项目 |
基于角色的访问控制(RBAC)
一、基于角色的访问控制(RBAC)介绍
什么是基于角色的访问控制(RBAC)
Role-Based Access Control 基于角色的访问控制(RBAC)百度百科 其基本思想是,对系统操作的各种权限不是直接授予具体的用户,而是在用户集合与权限集合之间建立一个角色集合。 每一种角色对应一组相应的权限。 一旦用户被分配了适当的角色后,该用户就拥有此角色的所有操作权限。 这样做的好处是,不必在每次创建用户时都进行分配权限的操作,只要分配用户相应的角色即可,而且角色的权限变更比用户的权限变更要少得多,这样将简化用户的权限管理,减少系统的开销。 为什么要用RBAC正如介绍中所说,不同的人拥有不同的权限,使得系统更加合理,分级治之!!! 二、RBAC的数据库设计 RBAC系统表设计思路数据库表设计思路图 简单介绍下: 李四是这个系统的一个用户,他的角色是超级管理员admin,超级管理员的权限就是全部权限。 上述的五个表,只有三个表(用户表,角色表,菜单表)是真正的表, 用户角色表是将用户表和角色表通过主外键的关系相连接的,同样权限表就是将角色表和菜单表相互连接的表 数据库结构文件(用powerdesign打开) 用户表介绍比较简单 角色表介绍 用户角色表将用户表和角色表通过外键连接起来 菜单表介绍这个表比较复杂,解释下 举个例子: 商品管理(一级菜单): 商品分类管理(二级菜单)商品信息(二级菜单) 菜单编号(主键)菜单名称父级菜单ID父级菜单名称菜单类型(几级菜单)菜单URL菜单编码菜单图标菜单排序4商品管理01icon-product25商品分类4商品管理2crServelt?op=listcr:listcon-cr-list16商品信息4商品管理2productServelt?op=listproduct:listicon-product-list2这里的菜单编码如cr:list意思就是 分类 列表,无非就是为了看明白该数据是实现那个业务逻辑,没什么特殊用意!!! 菜单排序则是商品管理是所有一级菜单中的第二个,商品分类是商品管理的第一个二级菜单,商品信息是商品管理的第二个二级菜单。 数据库表和数据SQL源码源码链接 三、RBAC的功能实现 登录功能实现login.jsp(不做重点介绍) 登录页 用户名: 密码:看代码看得出登录页面设置十分简单,只有一个提交表单(后期完善吧) form表单请求的是/ebuy/systemUserServlet?op=login,一个servlet,并且传入参数op方便请求同一个servlet的不同方法。 当然登录是要访问数据库查询数据的,(代码后面留下来了,不重点说了!),根据用户名和密码来查询数据,dao层代码如下: /** * 具有权限控制的用户数据访问实现类 */ public class SystemUserDaoImpl implements SystemUserDao { @Override public SystemUser login(SystemUser systemUser) { Connection connection=null; PreparedStatement ps=null; ResultSet rs=null; try { String sql = "select * from system_userinfo where USERINFO_LOGINID=? and USERINFO_PASSWORD=? "; connection = JDBCUtils.getConnection(); ps = connection.prepareStatement(sql); ps.setString(1, systemUser.getUserinfo_loginid()); ps.setString(2,systemUser.getUserinfo_password()); rs = ps.executeQuery(); SystemUser systemUser1=createSystemUserByResultSet(rs); if (systemUser1.getUserinfo_loginid()==null){ return null; }else { return systemUser1; } }catch (Exception e){ e.printStackTrace(); } try { rs.close(); ps.close(); connection.close(); } catch (SQLException throwables) { throwables.printStackTrace(); } return null; } private SystemUser createSystemUserByResultSet(ResultSet rs) throws SQLException { SystemUser systemUser = new SystemUser(); while (rs.next()){ systemUser.setUserinfo_uid(rs.getString("userinfo_uid")); systemUser.setUserinfo_loginid(rs.getString("userinfo_loginid")); systemUser.setUserinfo_name(rs.getString("userinfo_name")); systemUser.setUserinfo_password(rs.getString("userinfo_password")); systemUser.setUserinfo_sex(rs.getString("userinfo_sex")); systemUser.setUserinfo_email(rs.getString("userinfo_email")); systemUser.setUserinfo_mobile(rs.getString("userinfo_mobile")); systemUser.setUserinfo_status(rs.getInt("userinfo_status")); } return systemUser; } } 查询菜单功能在登录成功后,我们根据登录用户的id来查询用户角色表中对应的角色id,然后通过角色菜单(权限表)来查询该用户的菜单项。 sql语句如下: String sql = "select p.* from system_role_permission rp ,system_permission p where rp.permission_id=p.permission_id and rp.role_id=( select r.role_id from system_userrole ur,system_userinfo u,system_role r where ur.userinfo_id=u.userinfo_uid and ur.role_id=r.role_id and u.userinfo_loginid=?) ";然后将查询到的菜单项打包成集合,返回至index.jsp进行遍历 index页面通过include指令指令包含了两个jsp,分别是admin-header.jsp和admin-left.jsp。 admin-header.jsp 返回前台页面 首页 用户 商品 订单 留言 新闻 管理员;;${sessionScope.USER.userinfo_name};;您好,今天是,欢迎回到管理后台。 您现在的位置:易买网 ; 管理后台该页面就只有两个重点,一个是basepath,一个是显示用户名。 basepath 就是方便网页之间请求资源url的,不明白可以看这个 显示用户名 之前我们在登录请求servlet时,将查询到的用户表信息保存至session,通过jsp的session就可以获取到。 admin-left.jsp代码源码: Title ${p1.permission_name} 新增${p2.permission_name}上述的代码适用于二级菜单(多级不适用,多级也会使得页面过于乱) 在标题的url上我们是根据数据库查询到的 实现角色管理上述我们已经说了角色管理等标题的url是数据库中查询出来的,然后我们可以看到该角色管理的url:systemRoleServlet?op=list, 可以看出是请求systemRoleServlet这个servlet,然后请求的方法是list,就是把数据库的role角色信息全部查询出来 dao层数据访问层直接查询全部的角色信息,保存至role的集合中,然后返回至roleList页面。 roleList和index页面一样,同样包含header页面和left页面。 授权按钮每个角色信息后面都有一个授权按钮,点击之后会根据不同的角色,显示当前角色具备的功能并“打钩”,其他功能则不“打钩”,效果如下: 当是超级管理员时: 商品管理员时: 那么是如何实现的呢??? 显示vtree树上述的菜单树其实是一个图层, 当我们点击授权时,授权,调用showdiv()方法, shoudiv()方法: var roleIds=''; function showdiv(roleId,roleName) { roleIds=roleId; //每点击一次进行一次刷新 document.getElementById("bg").style.display = "block"; document.getElementById("show").style.display = "block"; $("#roleName").html(roleName+"拥有的权限"); //ajax请求 $.ajax({ url:'systemPermissionServlet', type:'post', async:false, data:{ op:'getPermissionTreeByRoleId', roleId:roleId }, dataType:'json', success:function (data){ $.fn.zTree.init($("#treeDemo"), setting, data); } }) }该方法首先就是使得图层显现出来,然后执行ajax请求,然后ajax请求成功之后就会调用success函数,初始化树,从而将该被勾选的数据进行勾选。 授权角色并保存至数据库点击图层的ok按钮,触发savePermission()方法, function savePermission() { var zTree = $.fn.zTree.getZTreeObj("treeDemo"); var nodes = zTree.getCheckedNodes(); var permissionIds=''; for (var i = 0; i < nodes.length; i++) { if (i==nodes.length-1){ //最后一个不加逗号 permissionIds+=nodes[i].id; //跳出循环 break; } permissionIds+=nodes[i].id+","; }; $.ajax({ url:'systemPermissionServlet', type:'post', async:false, data:{ op:'updatePermission', /*全局变量,在点击授权时,在*showdiv方法中已经赋值*/ roleId:roleIds, permissionIdArray:permissionIds }, dataType:'json', success:function (data){ alert(data.msg); } }); alert("授权完成"); hidediv(); }同上面的显示vtree。 |
CopyRight 2018-2019 实验室设备网 版权所有 |